/* eslint-disable quote-props, @typescript-eslint/quotes, @typescript-eslint/indent, comma-dangle, prefer-arrow/prefer-arrow-functions, object-shorthand, max-len */

import { qualityReport as qr } from '../content/bibertool-qr-check'

const fieldSet = <%- fieldSet %>
const allowed = {
<%_ for (const [type, sets] of Object.entries(allowed)) { -%>
  <%= type -%>: [
    <%_ for (const set of sets) { -%>
      fieldSet.<%= set -%>,
    <%_ } -%>
  ],
<%_ } -%>
}
const required = [
  <%_ for (const [, {types, fields}] of Object.entries(required)) { -%>
    {
      types: new Set(<%- JSON.stringify(types) -%>),
      check: function(ref, report) {
        <%_ for (const field of fields) { -%>
          <%_ if (typeof field == 'string') { -%>
            if (!ref.has.<%= field -%>) report.push("Missing required field '<%= field -%>'")
          <%_ } else if (field.or) { -%>
            if (!(<%- field.or.map(field => "ref.has." + field).join(' || ') -%>)) report.push("At least one of <%- field.or.map(f => "'" + f + "'").join(' / ') -%> must be present")
          <%_ } else if (field.xor) { -%>
            if (!ref.has.<%= field.xor[0] -%> === !ref.has.<%= field.xor[1] -%>) report.push("Exactly one of <%- field.xor.map(f => "'" + f + "'").join(' / ') -%> must be present")
          <%_ } -%>
        <%_ } -%>
      }
    },
  <%_ } -%>
]

export function qualityReport(explanation: Record<string, string>): string[] {
  const type = this.entrytype.toLowerCase()

  if (!allowed[type]) return

  const unexpected: string[] = Object.keys(this.has).filter((field: string) => !allowed[type].find((set: Set<string>) => set.has(field)))
  const report: string[] = unexpected.map(field => "Unexpected field '" + field + "'" + (explanation[field] ? (' (' + explanation[field] + ')'): ''))

  for (const test of required) {
    if (test.types.has(type)) test.check(this, report)
  }

  <%_ for (const [, {test, fields, params}] of Object.entries(data)) { -%>
    for (const field of <%- JSON.stringify(fields) -%>) {
      if (this.has[field]) {
        const warning = qr(this.has[field].value, <%- JSON.stringify(test) -%><%- typeof params === 'undefined' ? '' : ', ' + JSON.stringify(params) -%>)
        if (warning) report.push("'" + field + "': " + warning)
      }
    }
  <%_ } -%>

  return report
}
